package services

import (
	"bytes"
	"context"
	"crypto/tls"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/sirupsen/logrus"
	"io"
	"net/http"
	"net/url"
	"strconv"
	"strings"
	"time"
	"wecom_rebot/common"
	"wecom_rebot/core"
	"wecom_rebot/models"
)

var localCopyAccountLogger *logrus.Logger

// InitLocalAccountCopyLogger 移除 init() 函数，改为显式初始化函数
func InitLocalAccountCopyLogger() {
	// 确保在 common 初始化后调用
	localCopyAccountLogger = core.InitLogger(common.LogsErrorMap[13])
}

// HugeLocalCopyAccount 消息结构体
type HugeLocalCopyAccount struct {
	AccountName       string
	MerchantID        string
	AccountID         string
	WithoutID         int64
	Contact           string
	MobilePhoneNumber string
	Email             string
	Person            string
	CopyNumber        int
}

// Response 定义API响应结构
type Response struct {
	Code int    `json:"code"`
	Msg  string `json:"msg"`
	Data Data   `json:"data"`
}

// Data 定义数据部分结构
type Data struct {
	Total int       `json:"total"`
	List  []Account `json:"data"`
}

// Account 定义账户信息结构
type Account struct {
	LifeAccountId    int64  `json:"lifeAccountId"`
	LifeAccountName  string `json:"lifeAccountName"`
	AuthorizedStatus int    `json:"authorizedStatus"`
	ApplicantId      string `json:"applicantId"`
	ApplicantName    string `json:"applicantName"`
}

// 添加账号状态映射
var accountStatus = map[int]string{
	1: "授权中",
	2: "已授权",
	4: "已关闭",
	5: "已拒绝",
}

type CompanyHistoryResponse struct {
	Code int         `json:"code"`
	Msg  string      `json:"msg"`
	Data HistoryData `json:"data"`
}

type HistoryData struct {
	Total int       `json:"total"`
	List  []Company `json:"data"`
}

type Company struct {
	FirstIndustryId  string `json:"firstIndustryId"`
	SecondIndustryId string `json:"secondIndustryId"`
	LicenseProvince  string `json:"licenseProvince"`
	LicenseCity      string `json:"licenseCity"`
}

// companyNumberResponse 获取开户最大数量的返回结果
type companyNumberResponse struct {
	Code int    `json:"code"`
	Msg  string `json:"msg"`
	Data struct {
		AccountNum int `json:"accountNum"`
		LimitNum   int `json:"limitNum"`
	} `json:"data"`
}

// DocumentNumberResponse 获取证件号码
type DocumentNumberResponse struct {
	Code int    `json:"code"`
	Msg  string `json:"msg"`
	Data struct {
		LicenseNo       string `json:"licenseNo"`
		LicenseType     string `json:"licenseType"`
		LicenseTypeDesc string `json:"licenseTypeDesc"`
		LifeAccountName string `json:"lifeAccountName"`
	} `json:"data"`
}

// 提交复制的返回结果
type checkCopyResponse struct {
	Code int    `json:"code"`
	Msg  string `json:"msg"`
}

// 开户返回的结果
type createResponse struct {
	Code int             `json:"code"`
	Msg  string          `json:"msg"`
	Data json.RawMessage `json:"data"`
}

type createResponseData struct {
	ErrorState int    `json:"errorState"`
	CustomerId string `json:"customerId"`
	AdvId      string `json:"advId"`
	AdvName    string `json:"advName"`
	Msg        string `json:"msg"`
}

type lookupResponse struct {
	Code int             `json:"code"`
	Msg  string          `json:"msg"`
	Data json.RawMessage `json:"data"`
}

type HugeLocalCopyAccountService struct{}

func (s *HugeLocalCopyAccountService) Handle(msgId int, subjectName, roomId string, content []string, jobId uint64) error {

	var msg = &models.Msg{}

	fmt.Println("localCopyAccountLogger", "原始结构Id：", msgId)
	// 获取数据
	err := common.DB.Where("id = ?", msgId).First(&msg).Error
	if err != nil {
		localCopyAccountLogger.Error("巨量本地推获取数据失败", common.LogsErrorMap[2], msgId, err)
		return err
	}

	localCopyAccountLogger.Info("localCopyAccountLogger", "原始结构：", content)

	// 处理需要的数据结构
	result, err := s.analyzeContent(content)
	if err != nil {
		localCopyAccountLogger.Error(err)
		return err
	}

	// 移除功能行
	msg.Content = RemoveTitle(msg)
	localCopyAccountLogger.Info("localCopyAccountLogger", result, "移除后的结构：", msg, "广告主信息：", content)

	if result.CopyNumber > 10 {
		return errors.New("复制数量不能大于10个")
	}

	rdb := core.InitRedis(13)
	ctx := context.Background()

	cookies, err := rdb.Get(ctx, "laravel_database_oead_adv_cookies").Result()

	fmt.Println("localCopyAccountLogger", "Cookies:", cookies)

	// 查询任务
	var job models.Job
	if err = common.DB.Where("id = ?", jobId).First(&job).Error; err != nil {
		localCopyAccountLogger.Error("查询完整任务记录", common.LogsErrorMap[2], jobId, err)
		return err
	}

	var successResponse []string
	for i := 0; i < result.CopyNumber; i++ {

		var local models.ImportOelocal
		err := common.DBDk.Where("account_id = ? AND is_old = 1", result.AccountID).Take(&local).Error
		if err != nil {
			adCopyAccountTxLogger.Warnf("OA不存在ID: %s", result.AccountID)
			return errors.New("OA本地推不存在ID" + err.Error())
		}

		// 第一步 先校验商家是否授权
		_, err = s.checkAuthorization(result.MerchantID, cookies)
		if err != nil {
			localCopyAccountLogger.Error("校验商家授权", common.LogsErrorMap[2], result.MerchantID, err)
			return fmt.Errorf("媒体提示1：%v", err)
		}

		// 第四步 获取证件号码
		documentInfo, err := s.getDocumentNumber(result.MerchantID, cookies)
		if err != nil {
			localCopyAccountLogger.Warnf("获取证件号码失败: %v", err)
			return err
		}

		// 第二步 根据商家ID 获取公司名称
		companyInfo, err := s.getCompanyNameHistory(result.AccountName, cookies)
		if err != nil {
			localCopyAccountLogger.Error("获取公司名称", common.LogsErrorMap[2], result.AccountName, err)
			return fmt.Errorf("媒体提示2：%v", err)
		}
		localCopyAccountLogger.Info("第二步获取的信息：", companyInfo)

		// 第三步 最大开户数量和当前开户数量
		companyNumber, err := s.getCompanyOpenNumber(result.AccountName, documentInfo.Data.LicenseNo, documentInfo.Data.LicenseType, cookies)
		if err != nil {
			localCopyAccountLogger.Error("获取公司名称", common.LogsErrorMap[2], result.AccountName, err)
			return fmt.Errorf("媒体提示3：%v", err)
		}
		localCopyAccountLogger.Info("第三步获取的信息：", companyNumber)
		// 当前开户数量
		accountNum := companyNumber.Data.AccountNum

		var industryId int64
		var smallIndustryId int64

		// 检查返回码不为0的情况 如果没有行业返回链接媒介手动选择
		var industry models.OeSelectIndustry
		err = common.DBDk.Where("account_name = ? AND media = 'oelocal' AND account_id = ?", documentInfo.Data.LifeAccountName, result.AccountID).Take(&industry).Error
		// 如果存在
		if err == nil {
			industryId = industry.FirstIndustryCode
			smallIndustryId = industry.SecondIndustryCode
		} else {
			// 第五步 查询直客信息
			searchResponse, err := s.getSearchWithout(documentInfo.Data.LifeAccountName, documentInfo.Data.LicenseNo, documentInfo.Data.LicenseType, cookies)
			if err != nil {
				if err.Error() == "资质信息为空！" {
					encodedName := url.QueryEscape(documentInfo.Data.LifeAccountName)
					// 拼接完整的 URL
					sprintfUrl := fmt.Sprintf("https://web.disbursements.ecoremedia.net/#/other/account_industry?account_name=%s&media=oelocal&account_id=%s", encodedName, result.AccountID)
					if err := BendiSendText(msg.Content+"\n-----------------------------------\n直客未存在情况，请点击链接手动设置行业"+"\n"+sprintfUrl, msg.RoomID, msg.Sender); err != nil {
						return errors.New("直客未存在情况，发送链接失败")
					}
					return nil
				}
				localCopyAccountLogger.Warnf("获取直客信息失败: %v", err)
				return err
			}

			for _, value := range searchResponse {
				if value.CustomerID == result.WithoutID {
					industryId = value.IndustryId
					smallIndustryId = value.SmallIndustryId
					break
				}
			}
		}

		if industryId == 0 || smallIndustryId == 0 {
			return errors.New("一二级行业未找到")
		}

		num := accountNum + 1
		accountName := result.AccountName + "-yx-" + strconv.Itoa(num)
		// 第六步 提交复制户信息

		err = s.checkCopy(num, accountName, cookies)
		if err != nil {
			return errors.New("提交复制户失败" + err.Error())
		}

		makeData := map[string]interface{}{
			"localAccountType":     1,
			"company":              result.AccountName,
			"license_type":         documentInfo.Data.LicenseType,
			"license_no":           documentInfo.Data.LicenseNo,
			"agentId":              "1793206833630283",
			"name":                 accountName,
			"shopId":               result.MerchantID,
			"contacter":            result.Contact,
			"phonenumber":          result.MobilePhoneNumber,
			"email":                result.Email,
			"systemOrigin":         104,
			"accountCate":          8,
			"first_industry_code":  industryId,
			"second_industry_code": smallIndustryId,
			"license_country":      17487275,
			"license_country_name": "中国",
			"license_province":     companyInfo.LicenseProvince,
			"license_city":         companyInfo.LicenseCity,
			"license_type_name":    documentInfo.Data.LicenseTypeDesc,
		}

		localCopyAccountLogger.Info("组装提交的数据：", makeData)
		// 第七步 同意开户
		createSuccess, err := s.createFirstState(makeData, cookies)
		if err != nil {
			localCopyAccountLogger.Error("提交开户数据失败：", err)
			return errors.New("开户失败" + err.Error())
		}

		// 将开户成功的记录下来
		successResponse = append(successResponse, createSuccess.AdvId)
		// 将开户信息记录到 copy_account_list 表中
		accountID, _ := strconv.Atoi(createSuccess.AdvId)
		parentAccountID, _ := strconv.Atoi(result.AccountID)

		createCopy := &models.CopyAccountList{
			Parent:       parentAccountID,
			AccountID:    accountID,
			HandleStatus: 1,
			Username:     result.Person,
			Type:         4,
			AccountName:  createSuccess.AdvName,
		}

		err = common.DB.Create(createCopy).Error
		if err != nil {
			localCopyAccountLogger.Errorf("数据入库异常: %v, 数据: %v", err, createCopy)
			return errors.New("数据入库异常，请检查日志: " + err.Error())
		}
	}
	if len(successResponse) > 0 {
		if err := BendiSendText(msg.Content+"\n-----------------------------------\n复制成功："+strings.Join(successResponse, ","), msg.RoomID, msg.Sender); err != nil {
			localCopyAccountLogger.Errorf("复制成功发送消息失败: %v", err)
			return errors.New("复制成功发送消息失败: " + err.Error())
		}
	}
	return nil
}

// 同意开户
func (s *HugeLocalCopyAccountService) createFirstState(data map[string]interface{}, cookies string) (*createResponseData, error) {
	createUrl := "https://agent.oceanengine.com/agent/adv-create/add/first/state/"

	var createRes createResponse
	err := s.SendCurlRequest(createUrl, data, cookies, "POST", "", &createRes)
	if err != nil {
		localCopyAccountLogger.Infof("createFirstState请求失败: %v", err)
		return nil, fmt.Errorf("创建开户失败1: %v", err)
	}

	localCopyAccountLogger.Info("createFirstState原始响应: %+v", createRes)

	if createRes.Code != 0 {
		localCopyAccountLogger.Info("createRes.Code:", createRes.Msg, "返回参数:", createRes)
		return nil, fmt.Errorf("创建开户失败2: %v", createRes.Msg)
	}

	var res createResponseData
	err = json.Unmarshal(createRes.Data, &res)
	if err != nil {
		return nil, fmt.Errorf("创建开户失败3解析失败: %v", err)
	}

	//if createRes.Data.ErrorState != 0 {
	//	localCopyAccountLogger.Info("ErrorState:", createRes.Data.Msg, "返回参数:", createRes)
	//	return nil, fmt.Errorf("创建开户失败3: %v", createRes.Data.Msg)
	//}

	return &res, nil
}

// 提交复制户信息
func (s *HugeLocalCopyAccountService) checkCopy(num int, accountName, cookies string) error {
	copyUrl := fmt.Sprintf("https://agent.oceanengine.com/agent/adv-create/name/check/?accountCate=%d&advName=%s", num, accountName)

	var copyRes checkCopyResponse
	err := s.SendCurlRequest(copyUrl, nil, cookies, "GET", "", &copyRes)
	if err != nil {
		localCopyAccountLogger.Error("发送复制请求失败1:", err, "返回结果：", copyRes)
		return fmt.Errorf("发送复制请求失败1: %v", err)
	}

	localCopyAccountLogger.Info("复制请求结果:", copyRes)

	if copyRes.Code != 0 {
		localCopyAccountLogger.Error("发送复制请求失败2:", err, "返回结果：", copyRes)
		return fmt.Errorf("发送复制请求失败2: %v", err)
	}

	return nil
}

// 获取直客信息
func (s *HugeLocalCopyAccountService) getSearchWithout(customerName, licenseNo, licenseType, oeAdCookies string) ([]SearchWithoutCustomerResponse, error) {
	sprintfUrl := fmt.Sprintf("https://agent.oceanengine.com/agent/adv-create/customer/query?customerName=%s&licenseNo=%s&licenseType=%s", customerName, licenseNo, licenseType)

	var response lookupResponse
	err := s.SendCurlRequest(sprintfUrl, nil, oeAdCookies, "GET", "", &response)
	if err != nil {
		localCopyAccountLogger.Errorf("获取直客信息失败: %v", err)
		return nil, err
	}

	// 记录完整响应
	localCopyAccountLogger.Infof("getSearchWithout获取直客完整信息: %+v", response)

	// 检查返回码不为0的情况
	if response.Code != 0 {
		localCopyAccountLogger.Warnf("getSearchWithout获取直客信息失败: %s", response.Msg)
		return nil, errors.New(response.Msg)
	}

	// 检查data为空的情况
	if len(response.Data) == 0 {
		localCopyAccountLogger.Warnf("getSearchWithout未找到对应的授权信息: %s", response.Msg)
		return nil, fmt.Errorf("未找到直客信息: %s", response.Msg)
	}

	var result []SearchWithoutCustomerResponse

	if len(response.Data) > 0 {
		if err := json.Unmarshal(response.Data, &result); err != nil {
			localCopyAccountLogger.Errorf("解析快手响应data失败: %v", err)
			return nil, errors.New("解析快手响应失败")
		}
	}
	return result, nil
}

// 获取证件号码
func (s *HugeLocalCopyAccountService) getDocumentNumber(lifeAccountId string, cookies string) (*DocumentNumberResponse, error) {
	documentUrl := fmt.Sprintf("https://agent.oceanengine.com/agent/adv-create/localPromotion/query?lifeAccountId=%s", lifeAccountId)

	var result DocumentNumberResponse
	err := s.SendCurlRequest(documentUrl, nil, cookies, "GET", "", &result)
	if err != nil {
		localCopyAccountLogger.Error("获取证件号码失败1", result)
		return nil, err
	}

	localCopyAccountLogger.Info("获取证件原始信息：", result)

	if result.Code != 0 {
		localCopyAccountLogger.Error("获取证件号码失败2", result)
		return nil, fmt.Errorf("获取证件号码失败2: %s", result.Msg)
	}

	return &result, nil
}

// 获取账户名称的最大开户数量和当前开户数量
func (s *HugeLocalCopyAccountService) getCompanyOpenNumber(companyName, licenseNo, licenseType, cookie string) (*companyNumberResponse, error) {
	numberUrl := fmt.Sprintf("https://agent.oceanengine.com/agent/adv-create/localPromotion/accountNum?companyName=%s&licenseNo=%s&licenseType=%s&localAccountType=1", companyName, licenseNo, licenseType)

	var companyNumber companyNumberResponse
	err := s.SendCurlRequest(numberUrl, nil, cookie, "GET", "", &companyNumber)
	if err != nil {
		localCopyAccountLogger.Errorf("获取公司开通数量失败: %v", err)
		return nil, err
	}

	if companyNumber.Code != 0 {
		localCopyAccountLogger.Error("获取公司开通数量失败", companyNumber)
		return nil, fmt.Errorf("获取公司开通数量失败: %s", companyNumber.Msg)
	}

	localCopyAccountLogger.Infof("公司开通数量: %v", companyNumber)

	return &companyNumber, nil
}

// 根据商家ID 获取公司名称
func (s *HugeLocalCopyAccountService) getCompanyNameHistory(companyName, cookie string) (*Company, error) {
	historyUrl := fmt.Sprintf("https://agent.oceanengine.com/agent/localPromotion/list/?companyName=%s&page=1&size=1", companyName)

	var companyHistoryResponse CompanyHistoryResponse
	err := s.SendCurlRequest(historyUrl, nil, cookie, "GET", "", &companyHistoryResponse)
	if err != nil {
		localCopyAccountLogger.Errorf("获取公司名称历史失败: %v", err)
		return nil, err
	}

	if companyHistoryResponse.Code != 0 {
		localCopyAccountLogger.Error("获取公司历史名称失败:", companyHistoryResponse)
		return nil, fmt.Errorf("获取公司历史名称失败: %s", companyHistoryResponse.Msg)
	}

	if companyHistoryResponse.Data.Total == 0 {
		localCopyAccountLogger.Error("getCompanyNameHistory未找到对应的授权信息:", companyHistoryResponse)
		return nil, errors.New("未找到公司名称历史")
	}

	localCopyAccountLogger.Info("获取公司历史名称结果: %+v", companyHistoryResponse)

	return &companyHistoryResponse.Data.List[0], nil

}

// 校验商家是否授权
func (s *HugeLocalCopyAccountService) checkAuthorization(lifeAccountId, cookie string) (*Account, error) {
	checkUrl := "https://agent.oceanengine.com/agent/optimize/localPromotion/list?lifeAccountId=" + lifeAccountId + "&page=1&size=10"

	var req Response
	err := s.SendCurlRequest(checkUrl, nil, cookie, "GET", "", &req)
	if err != nil {
		localCopyAccountLogger.Errorf("checkAuthorization获取商家是否授权: %v", err)
		return nil, err
	}

	localCopyAccountLogger.Info("记录完整的返回信息：", req)

	if req.Code != 0 {
		localCopyAccountLogger.Error("获取商家是否授权失败:", req)
		return nil, fmt.Errorf(req.Msg)
	}

	if req.Data.Total == 0 {
		localCopyAccountLogger.Error("checkAuthorization未找到对应的授权信息：", req)
		return nil, errors.New("媒体后台中未查询到授权信息")
	}

	account := req.Data.List[0]
	if account.AuthorizedStatus != 2 {
		localCopyAccountLogger.Info("checkAuthorization客户暂未同意授权：", req)
		statusName := "未知状态"
		if name, ok := accountStatus[account.AuthorizedStatus]; ok {
			statusName = name
		}
		return nil, fmt.Errorf("账号 %s  授权状态：%s", lifeAccountId, statusName)
	}

	return &account, nil
}

// SendCurlRequest 发送HTTP请求
func (s *HugeLocalCopyAccountService) SendCurlRequest(url string, postData interface{}, xhsCookies string, method string, oeCsrfToken string, result interface{}) error {
	// 创建请求上下文
	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
	defer cancel()

	// 序列化POST数据
	var bodyReader io.Reader
	if postData != nil {
		jsonData, err := json.Marshal(postData)
		if err != nil {
			return fmt.Errorf("JSON序列化失败: %v", err)
		}
		bodyReader = bytes.NewBuffer(jsonData)
	}

	// 创建请求
	req, err := http.NewRequestWithContext(ctx, method, url, bodyReader)
	if err != nil {
		return fmt.Errorf("创建请求失败: %v", err)
	}

	// 设置请求头
	req.Header.Set("Content-Type", "application/json;charset=UTF-8")
	req.Header.Set("Cookie", xhsCookies)
	if oeCsrfToken != "" {
		req.Header.Set("Cg-Csrf-Token", oeCsrfToken)
	}

	// 创建自定义客户端
	client := &http.Client{
		Transport: &http.Transport{
			TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
		},
	}

	// 发送请求
	resp, err := client.Do(req)
	if err != nil {
		return fmt.Errorf("请求失败: %v", err)
	}
	defer resp.Body.Close()

	// 读取响应体
	respBody, err := io.ReadAll(resp.Body)
	if err != nil {
		return fmt.Errorf("读取响应失败: %v", err)
	}

	localCopyAccountLogger.Info("获取后得参数格式：", string(respBody))

	if result != nil {
		if err := json.Unmarshal(respBody, &result); err != nil {
			return fmt.Errorf("JSON解析失败: %v", err)
		}
	}
	return nil
}

// analyzeContent 解析内容为广告主信息数组
func (s *HugeLocalCopyAccountService) analyzeContent(content []string) (*HugeLocalCopyAccount, error) {
	// 初始化结果变量
	var accountName string
	var accountID string
	var merchantID string
	var withoutIDStr string
	var withoutID int64
	var contact string
	var mobilePhoneNumber string
	var email string
	var person string
	var copyNumber int

	// 遍历内容行
	for _, line := range content {
		// 账户名称
		if strings.HasPrefix(line, "账户名称:") {
			accountName = strings.TrimSpace(strings.TrimPrefix(line, "账户名称:"))
		}
		// OA账户ID
		if strings.HasPrefix(line, "OA账户ID:") {
			accountID = strings.TrimSpace(strings.TrimPrefix(line, "OA账户ID:"))
		}
		// 商家ID
		if strings.HasPrefix(line, "商家ID:") {
			merchantID = strings.TrimSpace(strings.TrimPrefix(line, "商家ID:"))
		}
		// 直客ID
		if strings.HasPrefix(line, "直客ID:") {
			withoutIDStr = strings.TrimSpace(strings.TrimPrefix(line, "直客ID:"))
		}
		// 联系人姓名
		if strings.HasPrefix(line, "联系人姓名:") {
			contact = strings.TrimSpace(strings.TrimPrefix(line, "联系人姓名:"))
		}
		// 手机号
		if strings.HasPrefix(line, "手机号:") {
			mobilePhoneNumber = strings.TrimSpace(strings.TrimPrefix(line, "手机号:"))
		}
		// 邮箱
		if strings.HasPrefix(line, "邮箱:") {
			email = strings.TrimSpace(strings.TrimPrefix(line, "邮箱:"))
		}
		// 复制数量
		if strings.HasPrefix(line, "复制数量:") {
			strValue := strings.TrimSpace(strings.TrimPrefix(line, "复制数量:"))
			if strValue != "" {
				var err error
				copyNumber, err = strconv.Atoi(strValue)
				if err != nil {
					localCopyAccountLogger.Errorf("复制数量转换失败: %v", err)
					return nil, fmt.Errorf("复制数量格式错误: %w", err)
				}
			}
		}
		// 媒介姓名
		if strings.HasPrefix(line, "媒介姓名:") {
			person = strings.TrimSpace(strings.TrimPrefix(line, "媒介姓名:"))
		}
	}

	if accountName == "" || accountID == "" || merchantID == "" || contact == "" || email == "" || mobilePhoneNumber == "" || person == "" || copyNumber == 0 {
		localCopyAccountLogger.Warn("请检查参数是否正确")
		return nil, errors.New("解析参数失败: 请检查参数是否正确")
	}

	// 转换 withoutID 为 int64
	if withoutIDStr != "" {
		var err error
		withoutID, err = strconv.ParseInt(withoutIDStr, 10, 64)
		if err != nil {
			localCopyAccountLogger.Errorf("直客ID转换失败: %v", err)
			return nil, fmt.Errorf("直客ID格式错误: %w", err)
		}
	}

	return &HugeLocalCopyAccount{
		AccountName:       accountName,
		MerchantID:        merchantID,
		AccountID:         accountID,
		WithoutID:         withoutID,
		Contact:           contact,
		MobilePhoneNumber: mobilePhoneNumber,
		Email:             email,
		Person:            person,
		CopyNumber:        copyNumber,
	}, nil
}
